class ThermoProjFire extends PainterFire;

#exec obj load file=GeneralAmbience.uax

var() class<ThermoBeamEffect> BeamEffectClass;

var() class<xEmitter> HitEmitterClass;
var() class<xEmitter> SecHitEmitterClass;
var() int NumArcs;
var() float SecDamageMult;
var() float SecTraceDist;
var() float HeadShotDamageMult;
var() float HeadShotRadius;
var() class<DamageType> DamageTypeHeadShot;
/*
var ThermoBeamEffect Beam;
var float UpTime;
var bool bDoHit;
var bool bValidMark;
var bool bInitialMark;
var bool bAlreadyMarked;

var IonCannon IonCannon;
var float MarkTime;
var Vector MarkLocation;
var() float TraceRange;
var() float PaintDuration;
var Vector EndEffect;
var   class<DamageType>	   MyDamageType;

var() Sound MarkSound;
var() sound AquiredSound;

var() string TAGFireForce;
var() string TAGMarkForce;
var() String TAGAquiredForce;
var bool bMarkStarted;*/
var   class<DamageType>	   DamageType;

var bool bInitAimError;
var rotator DesiredAimError, CurrentAimError;

var xEmitter MuzFlare;
var() int BerserkDamage;

/*
function Destroyed()
{
    if (Beam != None)
    {
        Beam.Destroy();
    }

    if (MuzFlare != None){
	MuzFlare.Destroy();}

    Super.Destroyed();
}
*/

state Paint
{
	function Rotator AdjustAim(Vector Start, float InAimError)
	{
			local Bot B;

			B = Bot(Instigator.Controller);

//		if ( Bot(Instigator.Controller) != None )
//		{
//	return Rotator(((B.Enemy.Location + B.Enemy.CollisionHeight * vect(0,0,1)) - Start)+VRand()*FRand()*25);
//		}
//		else
			return Global.AdjustAim(Start, 300); //InAimError);
	}

    function BeginState()
    {
     local bool bAmmo;

					   IonCannon = None;
        bAmmo = Weapon.AmmoAmount(0) > 0;

	if (MuzFlare==None)
	{
		MuzFlare = Spawn(class'ThermoFlare');
//		ThermoProj(Instigator.Weapon).AttachToBone(MuzFlare, 'tip' );
		Weapon(Owner).AttachToBone(MuzFlare, 'tip' );
	}

        if (Weapon.Role == ROLE_Authority)
        {
            if (Beam == None)
            {
                 Weapon.PlaySound(sound'GeneralAmbience.steamfx4');
		 Instigator.AmbientSound=Sound'WeaponSounds.LinkGun.BLinkGunBeam2';
                 Beam = Spawn(BeamEffectClass, Weapon);
            }
//            bInitialMark = false;		//true
//            bValidMark = false;
//            MarkTime = Level.TimeSeconds;
            SetTimer(0.25, true);
        }

        ClientPlayForceFeedback(TAGFireForce);
    }

    function Timer()
    {
        bDoHit = true;
    }

    function ModeTick(float dt)
    {

    local Vector StartTrace;
    local Rotator R, Aim;
    local float Step;

//100

    if (Beam != None)
    Beam.SetTargetState(PTS_Aiming);

		if(Weapon.AmmoAmount(0) > 0)
		{
			if (MuzFlare != None)
				MuzFlare.LifeSpan=0.5;

			StartTrace = Instigator.Location + Instigator.EyePosition();

				if ( Bot(Instigator.Controller) != None )
		                {
				if ( bInitAimError )
				{
					CurrentAimError = AdjustAim(StartTrace, AimError);
					bInitAimError = false;
				}
				else
				{
					BoundError();
					CurrentAimError.Yaw = CurrentAimError.Yaw + Instigator.Rotation.Yaw;
				}
				// smooth aim error changes
				Step = 7500.0 * dt;
				if ( DesiredAimError.Yaw ClockWiseFrom CurrentAimError.Yaw )
				{
					CurrentAimError.Yaw += Step;
					if ( !(DesiredAimError.Yaw ClockWiseFrom CurrentAimError.Yaw) )
					{
						CurrentAimError.Yaw = DesiredAimError.Yaw;
						DesiredAimError = AdjustAim(StartTrace, AimError);
					}
				}
				else
				{
					CurrentAimError.Yaw -= Step;
					if ( DesiredAimError.Yaw ClockWiseFrom CurrentAimError.Yaw )
					{
						CurrentAimError.Yaw = DesiredAimError.Yaw;
						DesiredAimError = AdjustAim(StartTrace, AimError);
					}
				}
				CurrentAimError.Yaw = CurrentAimError.Yaw - Instigator.Rotation.Yaw;
				if ( BoundError() )
					DesiredAimError = AdjustAim(StartTrace, AimError);
				CurrentAimError.Yaw = CurrentAimError.Yaw + Instigator.Rotation.Yaw;

				Aim = Rotator(Instigator.Controller.Target.Location - StartTrace);

				Aim.Yaw = CurrentAimError.Yaw;

				// save difference
				CurrentAimError.Yaw = CurrentAimError.Yaw - Instigator.Rotation.Yaw;
				}
				else
	        	        Aim = AdjustAim(StartTrace, AimError);


//	    		Aim = AdjustAim(StartTrace, AimError);
			R = rotator(vector(Aim) + VRand()*FRand()*Spread);
	    		DoTrace(StartTrace, R);
	    		Weapon.ConsumeAmmo(0,1);
		}
		else
			StopFiring();


    if (!bIsFiring)
        {
            StopFiring();
        }

    }

    function StopFiring()
    {
	Instigator.AmbientSound=None;
//	bMarkStarted = false;
        if (Beam != None)
        {
            Beam.SetTargetState(PTS_Cancelled);
        }
        GotoState('');
    }

    function EndState()
    {
//      bAlreadyMarked = false;
        SetTimer(0, false);
        StopForceFeedback(TAGFireForce);
    }
}

function bool BoundError()
{
	CurrentAimError.Yaw = CurrentAimError.Yaw & 65535;
	if ( CurrentAimError.Yaw > 2048 )
	{
		if ( CurrentAimError.Yaw < 32768 )
		{
			CurrentAimError.Yaw = 2048;
			return true;
		}
		else if ( CurrentAimError.Yaw < 63487 )
		{
			CurrentAimError.Yaw = 63487;
			return true;
		}
	}
	return false;
}


function DoFireEffect()
{
}

function ModeHoldFire()
{
    GotoState('Paint');
}

function StartBerserk()
{
	FireRate=default.FireRate;
	BerserkDamage=4;
}

function StopBerserk()
{
	FireRate=default.FireRate;
	BerserkDamage=0;
}

function vector GetFireStart(vector X, vector Y, vector Z)
{
    return Instigator.Location + Instigator.EyePosition() + X*Instigator.CollisionRadius;
}

function DoTrace(Vector Start, Rotator Dir)
{
    local Vector X,Y,Z, End, HitLocation, HitNormal;
    local Actor Other;
    local int Damage, arcsRemaining;
    local class<Actor> tmpHitEmitClass;
    local float tmpTraceRange, dist;
    local vector arcEnd;

    Weapon.GetViewAxes(X, Y, Z);
    arcEnd = (Instigator.Location +
        Instigator.CalcDrawOffset(Weapon) +
        Weapon.EffectOffset.X * X +
        Weapon.EffectOffset.Y * Y +
        Weapon.EffectOffset.Z * Z);

    arcsRemaining = NumArcs;

    tmpHitEmitClass = HitEmitterClass;
    tmpTraceRange = TraceRange;


        X = Vector(Dir);
        End = Start + tmpTraceRange * X;
        Other = Trace(HitLocation, HitNormal, End, Start, true);

        if ( Other != None && Other != Instigator  )
        {
            if ( !Other.bWorldGeometry )
                {

		if ( Bot(Instigator.Controller) != None )
		    Damage = BerserkDamage + 6;
		else
                    Damage = BerserkDamage + 8;


		if ( Other.IsA('ONSPowerCore') || Other.IsA('ONSPowerNode') || Other.IsA('ONSPowerNodeEnergySphere'))
		{
			Other.TakeDamage(Damage*0.75 ,Instigator,HitLocation,250*X,DamageType);
		}

	    	if ( Other.IsA('Projectile') && Other.bProjTarget)
		{
			if ( Instigator.Role == ROLE_Authority )
			Other.TakeDamage(Damage ,Instigator,HitLocation,250*X,DamageType);
		}

		if ( (Pawn(Other) != None)
		&& Other.GetClosestBone( HitLocation, X, dist, 'head', HeadShotRadius ) == 'head' )
		{
                Other.TakeDamage(Damage * HeadShotDamageMult, Instigator, HitLocation, 250*X, DamageTypeHeadShot);
                }
		else
		{
																//			Damage *= SecDamageMult;
                    Other.TakeDamage(Damage, Instigator, HitLocation, 250*X, DamageType);
																				}
                } else  {
																HitLocation = HitLocation + 2.0 * HitNormal;
																}

								}
        else
        {
            HitLocation = End;
            HitNormal = Normal(Start - End);
								}

								if (Beam != None){
								Beam.SetTargetState(PTS_Marked);
								Beam.EndEffect = HitLocation;}
								TFThermoProj(Weapon).EndEffect = HitLocation;

}

defaultproperties
{
     BeamEffectClass=Class'Taskforces.ThermoBeamEffect'
     HitEmitterClass=Class'XEffects.IonLightBeam'
     SecHitEmitterClass=Class'Taskforces.ThermoBeamEffect'
     NumArcs=4
     SecDamageMult=0.400000
     SecTraceDist=300.000000
     HeadShotDamageMult=1.500000
     HeadShotRadius=8.000000
     DamageTypeHeadShot=Class'Taskforces.DamTypeThermoBeamHeadShot'
     TraceRange=32768.000000
     PaintDuration=200.000000
     DamageType=Class'Taskforces.DamTypeThermoBeam'
     MarkSound=Sound'WeaponSounds.TAGRifle.TAGFireB'
     AquiredSound=Sound'WeaponSounds.TAGRifle.TAGTargetAquired'
     TAGFireForce="TAGFireA"
     TAGMarkForce="TAGFireB"
     TAGAquiredForce="TAGAquire"
     bInitAimError=True
     bSplashDamage=False
     bRecommendSplashDamage=False
     FireRate=0.800000
     AmmoClass=Class'Taskforces.ThermoProjAmmo'
     BotRefireRate=0.100000
     aimerror=400.000000
}
